package com.example.demo.web.filter;

import com.alibaba.fastjson.JSON;
import com.example.demo.anno.PrePermission;
import com.example.demo.result.Result;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.RequestPath;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.reactive.HandlerMapping;
import org.springframework.web.reactive.result.method.RequestMappingInfo;
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import org.springframework.web.util.pattern.PathPattern;
import reactor.core.publisher.Mono;

import java.lang.annotation.Annotation;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Slf4j
@Order(2)
public class PermissionValidateFilter implements WebFilter {

    AntPathMatcher matcher = new AntPathMatcher();

    @Resource
    private RequestMappingHandlerMapping  handlerMappings;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {

        //获取执行的方法
        String path = exchange.getRequest().getPath().value();
        HandlerMethod handlerMethod = getHandlerMethod(path);
        //未找到方法不处理
        if(handlerMethod == null){
            return chain.filter(exchange);
        }
        //获取权限注解
        PrePermission annotation = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), PrePermission.class);

        //没有权限注解不处理
        if(annotation == null){
            return chain.filter(exchange);
        }

        //获取用户权限列表
        List<String> userPermissions = Arrays.asList("admin","hr");

        if(!userPermissions.contains(annotation.value())){
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            exchange.getResponse().getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8");
            //响应错误结果
            Result result = new Result(403,"无权限访问");
            byte[] bytes = JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8);
            DataBuffer dataBuffer = exchange.getResponse().bufferFactory().wrap(bytes);
            return exchange.getResponse().writeWith(Mono.just(dataBuffer));
        }

        return chain.filter(exchange);
    }

    private HandlerMethod getHandlerMethod(String path) {
        HandlerMethod handlerMethod = null;
        for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMappings.getHandlerMethods().entrySet()) {
            PathPattern first = (PathPattern) ((TreeSet) entry.getKey().getPatternsCondition().getPatterns()).first();
            if(matcher.match(first.getPatternString(), path)){
                handlerMethod = entry.getValue();
                break;
            }
        }
        return handlerMethod;
    }
}
